package com.better.backend.mqReceiverService.calType.calService;

import com.alibaba.fastjson.JSONObject;
import com.better.backend.dataComputingService.model.examAvg.ExamAvgCalModel;
import com.better.backend.dataComputingService.model.examAvg.ExamClassAvgCalModel;
import com.better.backend.dataComputingService.model.examAvg.ExamSubjectAvgCalModel;
import com.better.backend.dataComputingService.model.examAvg.ExamSubjectSchoolAvgCalModel;
import com.better.backend.dataComputingService.model.point.*;
import com.better.backend.dataComputingService.model.question.ExamSubjectStuQuestionCalModel;
import com.better.backend.dataComputingService.model.question.QuestionCalModel;
import com.better.backend.dataComputingService.model.question.QuestionStuCalModel;
import com.better.backend.dataComputingService.model.question.StudentQuestionCalModel;
import com.better.backend.dataComputingService.model.scoreSelection.*;
import com.better.backend.dataComputingService.model.stuScore.ExamStudentScoreCalModel;
import com.better.backend.dataComputingService.model.stuScore.StudentScoreCalModel;
import com.better.backend.dataComputingService.model.stuScore.SubujectScoreCalModel;
import com.better.backend.dataComputingService.repository.examAvgRespository.ExamAvgRepsitory;
import com.better.backend.dataComputingService.repository.pointRespository.PointRepsitory;
import com.better.backend.dataComputingService.repository.questionRespository.QuestionRepsitory;
import com.better.backend.dataComputingService.repository.scoreSelection.ScoreSelectionRespository;
import com.better.backend.dataComputingService.repository.scoreSelection.SeleExamStudentScoreRepsitory;
import com.better.backend.dataComputingService.repository.stuScoreRespository.ExamStuScoRepsitory;
import com.better.backend.mqReceiverService.calType.model.AvgUtilModel;
import com.better.backend.mqReceiverService.calType.model.CalTypeModel;
import com.better.backend.mqReceiverService.calType.model.SortUtil;
import com.better.backend.mqReceiverService.calType.repository.CalTypeRepsitory;
import com.better.backend.mqReceiverService.examReceiver.model.ExamModel;
import com.better.backend.mqReceiverService.examReceiver.model.ExamUnitModel;
import com.better.backend.mqReceiverService.examReceiver.model.SubjectScoreModel;
import com.better.backend.mqReceiverService.examReceiver.repository.ExamRepsitory;
import com.better.backend.mqReceiverService.questionReceiver.model.ExamPaperModel;
import com.better.backend.mqReceiverService.questionReceiver.model.PointPaperModel;
import com.better.backend.mqReceiverService.questionReceiver.model.QuestionModel;
import com.better.backend.mqReceiverService.questionReceiver.repository.ExamPaperRepsitory;
import com.better.backend.mqReceiverService.studentRecever.model.ScoreReceverModel;
import com.better.backend.mqReceiverService.studentRecever.model.StuScoreDetailModel;
import com.better.backend.mqReceiverService.studentRecever.model.StuScoreReceverModel;
import com.better.backend.mqReceiverService.studentRecever.repository.ScoreReceverModelRepository;
import com.better.common.base.ServiceResponse;
import com.better.common.jwtauth.secruity.JWTUserDetails;
import com.better.common.utils.*;
import com.better.consist.CalTypeEnum;
import com.better.consist.ExamEnum;
import com.better.consist.GlobalTypeEnum;
import com.better.util.BigDecimalUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author  计算类
 * @create 2017-11-13 15:32
 **/
@Service
public class CalService {
    private static Log log = LogFactory.getLog(CalService.class);
    @Autowired
    private CalTypeRepsitory calTypeRepsitory;
    @Autowired
    private ScoreReceverModelRepository scoreRepository;
    @Autowired
    private ExamStuScoRepsitory examStuScoRepsitory;
    @Autowired
    private ExamRepsitory examRepsitory;
    @Autowired
    private ExamAvgRepsitory examAvgRepsitory;
    @Autowired
    private ExamPaperRepsitory examPaperRepsitory;
    @Autowired
    private PointRepsitory pointRepsitory;
    @Autowired
    private ScoreSelectionRespository scoreSelectionRespository;
    @Autowired
    private SeleExamStudentScoreRepsitory seleExamStudentScoreRepsitory;
    @Autowired
    private QuestionRepsitory questionRepsitory;

    /**
     * 通过考试ID，计算学生成绩分析
     * @param examId
     */
    public void calculate(String examId){
        long beginTime = System.currentTimeMillis();
        log.info("开始计算考试ID为："+examId+"的考试分析。开始时间："+beginTime);
        //通过考试查询计算规则
        CalTypeModel calTypeModel = calTypeRepsitory.findByExamId(examId);
        ExamModel examModel = examRepsitory.findOne(examId);
        if(calTypeModel==null||examModel==null){
            log.info("计算终止，该考试分析模板为空，考试ID为"+examId);
            return;
        }
        if(ExamEnum.EXAM_STATUS_CALTYPE.getCode().toString().equals(examModel.getStatus())){
            //按班级计算学生总分，排名
            calTotalSco(examModel,calTypeModel);
            //计算完成，更新考试状态
            examModel.setStatus(ExamEnum.EXAM_STATUS_PUBLISH.getCode()+"");
            examModel.setStatusName(ExamEnum.EXAM_STATUS_PUBLISH.getName());
            examRepsitory.save(examModel);
            long endTime = System.currentTimeMillis()-beginTime;
            log.info("计算完成，考试ID为："+examId+"的考试分析。总耗时："+endTime);
        }
        else{
            log.info("计算终止，该考试状态为已计算完成，考试ID为"+examId);
        }
    }

    /**
     * 按班级计算学生排名,平均分,各科目总分
     * @param
     * @param calTypeModel
     */
    public void calTotalSco(ExamModel examModel,CalTypeModel calTypeModel){
        String examId = examModel.getId();
        List<ScoreReceverModel> scoreModelList = scoreRepository.findByExamId(examId);
        if(scoreModelList==null||scoreModelList.size()==0){
            log.info("计算终止，该考试成绩信息为空，考试ID为"+examId);
            return;
        }
        //key:gradeID+"-"+subjectID,value :　考试科目信息
        Map<String,SubjectScoreModel> subScoMap = getSubjectScoreMap(examModel);
            //班级考试计算
            ExamStudentScoreCalModel examStudentScore = new ExamStudentScoreCalModel();
            ScoreReceverModel sc = scoreModelList.get(0);
            examStudentScore.setExamType(sc.getExamType());
            examStudentScore.setSchoolId(sc.getSchoolId());
            examStudentScore.setExamName(sc.getExamName());
            examStudentScore.setExamId(examId);
            examStudentScore.setSchoolName(sc.getSchoolName());
            //按班级分组
            Map<String,List<ScoreReceverModel>> map = scoreModelList.stream().collect(Collectors.groupingBy(c->c.getClassId()));
            //存放年级对应，班级对应平均分信息
             Map<String,Map<String,ExamClassAvgCalModel>> avgMap = new HashMap<>();
            //按年级，科目分组，获取考试下科目对应知识点总分
            PointUtilMode pointUtilMode = getSubjectPointByExamId(examModel);
            Map<String,ExamSubjectStuPointCalModel> gradeSubPointMap = pointUtilMode.getReMap();
            Map<String,List<QuestionModel>> quesMap = pointUtilMode.getQuesMap();
        //按年级科目分组，存放计算后的小题分析
        Map<String,ExamSubjectStuQuestionCalModel> calQuesMap = pointUtilMode.getCalQuesMap();
        //用于保存所有存放数据库的知识点平均分实体，用于统计知识点年级平均分
        List<ExamSubjectStuPointCalModel> examSubjectStuPoints = new ArrayList<>();
        //用于保存所有存放数据库的小题平均分实体，用于统计小题年级平均分
        List<ExamSubjectStuQuestionCalModel> stuQuesList = new ArrayList<>();
            //每个科目班级学生得分排序，班级排名
           map.forEach((key,value)->{
               ScoreReceverModel scClass = value.get(0);
               examStudentScore.setClassId(scClass.getClassId());
               examStudentScore.setClassName(scClass.getClassName());
               examStudentScore.setGradeId(scClass.getGradeId());
               examStudentScore.setGradeName(scClass.getGradeName());
               examStudentScore.setId(GlobalUtil.createGlobalId());
               //根据班级科目分组
               Map<String,List<ScoreReceverModel>> mapSub = value.stream().collect(Collectors.groupingBy(c->c.getSubjectId()));
               //每个科目班级学生得分排序，班级排名
               mapSub.forEach((key1,value1)->value1.forEach(v->v.getScoreDetailList().sort((o1,o2)->o2.getTotalScore().compareTo(o1.getTotalScore()))));
               //存放学生各科成绩map
               Map<String,StudentScoreCalModel> stuMap = new HashMap<String, StudentScoreCalModel>();
               //单个科目班级总分，用于计算班级科目平均分
               Map<String,AvgUtilModel> scoMap = new HashMap<String, AvgUtilModel>();
                mapSub.forEach((key1,value1)->{
                    //计算学生知识点
                    ExamSubjectStuPointCalModel examSubjectStuPointa = gradeSubPointMap.get(scClass.getGradeId()+"-"+key1);
                    ExamSubjectStuPointCalModel examSubjectStuPoint = new ExamSubjectStuPointCalModel();
                    BeanUtils.copyProperties(examSubjectStuPointa,examSubjectStuPoint);
                    //学生小题得分情况
                    ExamSubjectStuQuestionCalModel examSubjectStuQuestionCalModela = calQuesMap.get(scClass.getGradeId()+"-"+key1);
                    ExamSubjectStuQuestionCalModel examSubjectStuQuestionCalModel = new ExamSubjectStuQuestionCalModel();
                    BeanUtils.copyProperties(examSubjectStuQuestionCalModela,examSubjectStuQuestionCalModel);
                    List<QuestionModel> quesList = quesMap.get(scClass.getGradeId()+"-"+key1);
                    if(examSubjectStuPoint==null||quesList==null){
                        log.info("年级对应科目的知识点Map为空，数据异常。考试ID："+examId+"。年级ID："+scClass.getGradeId()+"。科目ID："+key1);
                    }
                    examSubjectStuPoint.setId(GlobalUtil.createGlobalId());
                    examSubjectStuPoint.setExamId(examId);
                    examSubjectStuPoint.setClassId(scClass.getClassId());
                    examSubjectStuPoint.setClassName(scClass.getClassName());

                    examSubjectStuQuestionCalModel.setId(GlobalUtil.createGlobalId());
                    examSubjectStuQuestionCalModel.setExamId(examId);
                    examSubjectStuQuestionCalModel.setClassId(scClass.getClassId());
                    examSubjectStuQuestionCalModel.setClassName(scClass.getClassName());

                    List<PointCalModel> pointList = examSubjectStuPoint.getPointList();
                    //知识点分组
                    Map<String,List<PointCalModel>> pMap = pointList.stream().collect(Collectors.groupingBy(c->c.getPointId()));
                    //学生ID，学生成绩明细Map
                    Map<String,StuScoreReceverModel> stuIDStuScoreDetail = new HashMap<String, StuScoreReceverModel>();
                    value1.forEach(item->{
                        //设置该班级单科学生分数，排名
                        List<StuScoreReceverModel> stuScoreReceverModels = item.getScoreDetailList();
                        SortUtil sortUtil = new SortUtil();
                        stuScoreReceverModels.forEach(itema->{
                            StudentScoreCalModel stuSco = stuMap.get(itema.getStudentId());
                            stuIDStuScoreDetail.put(itema.getStudentId(),itema);
                            if(stuSco==null){
                                stuSco = new StudentScoreCalModel();
                                stuSco.setIDCard(itema.getIDCard());
                                stuSco.setStudentId(itema.getStudentId());
                                stuSco.setStudentName(itema.getStudentName());
                                stuSco.setStudentNo(itema.getStudentNo());
                                stuSco.setTotalScore(new Double(0));
                            }
                            List<SubujectScoreCalModel> subujectScoreList = stuSco.getSubujectScoreList();
                            if(subujectScoreList==null){
                                subujectScoreList = new ArrayList<SubujectScoreCalModel>();
                            }
                            //科目总分
                            stuSco.setTotalScore(stuSco.getTotalScore()+itema.getTotalScore());
                            //设置单科考试信息，得分，排名
                            SubujectScoreCalModel subujectScore = new SubujectScoreCalModel();
                            subujectScore.setSubjectId(item.getSubjectId());
                            subujectScore.setSubjectName(item.getSubjectName());
                            subujectScore.setClassSubjectSortNum(sortUtil.getNum());
                            subujectScore.setScore(itema.getTotalScore());
                            //计算百分比得分
                            SubjectScoreModel suMo = subScoMap.get(item.getGradeId()+"-"+item.getSubjectId());
                            subujectScore.setPercentScore(CalGetAvgUtil.getRate(suMo.getToalscore(),itema.getTotalScore().toString()));
                            subujectScoreList.add(subujectScore);
                            stuSco.setSubujectScoreList(subujectScoreList);
                            stuMap.put(itema.getStudentId(),stuSco);
                            //计算科目总分
                            AvgUtilModel avgUtilModel = scoMap.get(item.getSubjectId());
                            if(avgUtilModel==null){
                                avgUtilModel = new AvgUtilModel();
                                avgUtilModel.setNum(0);
                                avgUtilModel.setTotalScore(new Double(0));
                                avgUtilModel.setSubjectName(item.getSubjectName());
                                avgUtilModel.setSubjectId(item.getSubjectId());
                            }
                            //判断单科为0的是否纳入计算平均分
                            if(itema.getTotalScore().compareTo(new Double(0))==0){
                                if(CalTypeEnum.zeroType_t.equals(calTypeModel.getZeroType())){
                                    avgUtilModel.setTotalScore(avgUtilModel.getTotalScore()+itema.getTotalScore());
                                    avgUtilModel.setNum(avgUtilModel.getNum()+1);
                                }
                            }
                            else{
                                avgUtilModel.setTotalScore(avgUtilModel.getTotalScore()+itema.getTotalScore());
                                avgUtilModel.setNum(avgUtilModel.getNum()+1);
                            }
                            scoMap.put(item.getSubjectId(),avgUtilModel);
                        });
                    });
                    //循环学生科目得分明细，计算知识点得分
                    examSubjectStuPoint = calStuPoint(stuIDStuScoreDetail,quesList,examSubjectStuPoint,pMap,examSubjectStuQuestionCalModel);
                    examSubjectStuPoints.add(examSubjectStuPoint);
                    stuQuesList.add(examSubjectStuQuestionCalModel);
                });
               List<StudentScoreCalModel> inList = new ArrayList<StudentScoreCalModel>(stuMap.values());
                //计算学生总分平均分，班级排名
                inList.sort((in1,in2)->in2.getTotalScore().compareTo(in1.getTotalScore()));
               SortUtil su = new SortUtil();
                inList.forEach((item)->{
                    AvgUtilModel avgUtilModel = new AvgUtilModel();
                    avgUtilModel.setNum(item.getSubujectScoreList().size());
                    avgUtilModel.setTotalScore(item.getTotalScore());
                    item.setTotalAvg(avgUtilModel.calAvg(calTypeModel));
                    item.setClassSortNum(su.getNum());
                });
               examStudentScore.setStudentScoreList(inList);
                //一次考试一个班级的数据计算完成，保存数据
               examStuScoRepsitory.save(examStudentScore);
               //计算一个班级的科目平均分
               ExamClassAvgCalModel examClassAvgModel = calAvg(scoMap,calTypeModel,examStudentScore);
               Map<String,ExamClassAvgCalModel> map1 = avgMap.get(scClass.getGradeId());
               if(map1==null){
                   map1 = new HashMap<String, ExamClassAvgCalModel>();
               }
               map1.put(key,examClassAvgModel);
               avgMap.put(scClass.getGradeId(),map1);
               //avgMap.put(key,examClassAvgModel);
           });
            //计算年级知识点总平均得分率，失分率
            calGradePointAvgScore(examSubjectStuPoints);
            //计算年级小题总平均得分率，失分率，保存数据
            calGradeQuesAvgScore(stuQuesList);
            //计算学生年级排名，各科得分年级排名
            calStuSortInSchool(examId);
            //计算年级所有总平均分，排名等情况
            calTotalAvgAndSort(avgMap,calTypeModel,examModel);
    }

    /**
     * 通过考试ID，查询所有科目总分
     * @param
     * @return
     */
    public Map<String,SubjectScoreModel> getSubjectScoreMap(ExamModel examModel){
        Map<String,SubjectScoreModel> reMap = new HashMap<>();
        //ExamModel examModel = examRepsitory.findOne(examId);
        //如果是班级考试
        if(CalTypeEnum.examtype_class.equals(examModel.getExamType())){
            String gradeId = examModel.getGradeId();
            List<ExamUnitModel> examUnitModels = examModel.getExamUnitModels();
            List<SubjectScoreModel> subjectScoreModels = examUnitModels.get(0).getSubjectScoreModels();
            subjectScoreModels.forEach(s->reMap.put(gradeId+"-"+s.getSubjectid(),s));
        }
        //校级考试
        else{
            List<ExamUnitModel> examUnitModels = examModel.getExamUnitModels();
            examUnitModels.forEach(e->{
                String gradeId = e.getUnitId();
                List<SubjectScoreModel> subjectScoreModels = e.getSubjectScoreModels();
                subjectScoreModels.forEach(s->reMap.put(gradeId+"-"+s.getSubjectid(),s));
            });
        }
        return reMap;
    }

    /**
     * 计算年级小题知识点平均得分率，失分率，并保存数据
     * @param stuQuesList
     */
    public void calGradeQuesAvgScore(List<ExamSubjectStuQuestionCalModel> stuQuesList){
        //按年级科目分组，计算年级科目下所有小题得分率
        Map<String,List<ExamSubjectStuQuestionCalModel>> map = stuQuesList.stream().collect(Collectors.groupingBy(s->s.getGradeId()+"-"+s.getSubjectId()));
        for(List<ExamSubjectStuQuestionCalModel> list : map.values()){
            List<QuestionCalModel> questionCalModels = new ArrayList<>();
            for(ExamSubjectStuQuestionCalModel l : list){
                questionCalModels.addAll(l.getQuestionCalModels());
            }
            //按小题分组，求年级平均分，得分率
            Map<String,List<QuestionCalModel>> listQue = questionCalModels.stream().collect(Collectors.groupingBy(c->c.getQuesNo()));
            for(List<QuestionCalModel> littQ : listQue.values()){
                //求平均
                Double oAvg = littQ.stream().mapToDouble((p)->p.getClassReceAvgScore()).average().getAsDouble();
                //年级平均得分率(保留4为小数)
                Double rate = new BigDecimal(oAvg).divide(new BigDecimal(littQ.get(0).getScore()),4,BigDecimal.ROUND_HALF_UP).doubleValue();
                Double loseRate = 1-rate;
                for (QuestionCalModel qm : littQ){
                    qm.setGradeReceAvgScore(oAvg);
                    qm.setGradeReceAvgRate(rate);
                    qm.setGradeLoseAvgRate(loseRate);
                }
            }
        }
        //保存数据
        questionRepsitory.save(stuQuesList);
    }
    /**
     * 计算年级知识点总平均得分率，失分率，并保存数据库
     * @param examSubjectStuPoints
     */
    public void calGradePointAvgScore(List<ExamSubjectStuPointCalModel> examSubjectStuPoints){
        //按年级，科目分组,计算年级科目下知识点得分率
        Map<String,List<ExamSubjectStuPointCalModel>> map = examSubjectStuPoints.stream().collect(Collectors.groupingBy(ex->ex.getGradeId()+"-"+ex.getSubjectId()));
        for (List<ExamSubjectStuPointCalModel> list:map.values()) {
            List<PointCalModel> allList = new ArrayList<>();
            list.forEach((item)->{
                allList.addAll(item.getPointList());
            });
            //按知识点分组，求平均
            Map<String,List<PointCalModel>> poLIst = allList.stream().collect(Collectors.groupingBy(all->all.getPointId()));
            for (List<PointCalModel> listPo:poLIst.values()) {
                //求平均
                OptionalDouble oAvg = listPo.stream().mapToDouble((p)->p.getClassReceAvgRate()).average();
                listPo.forEach((l)->{
                    l.setGradeReceAvgRate(oAvg.getAsDouble());
                    l.setClassLoseAvgRate(1-oAvg.getAsDouble());
                });
            }
        }
        pointRepsitory.save(examSubjectStuPoints);
    }

    /**
     * 计算学生年级排名，各科得分年级排名
     * @param examId
     */
    public void calStuSortInSchool(String examId){
        List<ExamStudentScoreCalModel> examStudentScoresa = examStuScoRepsitory.findByExamId(examId);
        if(examStudentScoresa==null){
            log.info("计算学生年级排名异常，查询数据为空。考试ID："+examId);
            return;
        }
        //按年级分组
        Map<String,List<ExamStudentScoreCalModel>> gList = examStudentScoresa.stream().collect(Collectors.groupingBy(e->e.getGradeId()));
        for(List<ExamStudentScoreCalModel> examStudentScores:gList.values()){
            List<SubujectScoreCalModel> subujectScoreList = new ArrayList<>();
            List<StudentScoreCalModel> stuList = new ArrayList<>();
            examStudentScores.forEach((item)->{
                stuList.addAll(item.getStudentScoreList());
            });
            //学生总分年级排名
            stuList.sort((stu1,stu2)->stu2.getTotalScore().compareTo(stu1.getTotalScore()));
            SortUtil sor = new SortUtil();
            stuList.forEach((stu)->{
                stu.setSchoolSortNum(sor.getNum());
                subujectScoreList.addAll(stu.getSubujectScoreList());
            });
            //计算学生单科得分年级排名
            //按科目分组
            Map<String,List<SubujectScoreCalModel>> stuSubScoreMap = new HashMap<>();
            stuSubScoreMap = subujectScoreList.stream().collect(Collectors.groupingBy(gr->gr.getSubjectId()));
            //按科目循环Map,计算学校排名
            stuSubScoreMap.forEach((key,value)->{
                value.sort((v1,v2)->v2.getScore().compareTo(v1.getScore()));
                sor.reSetNum();     //重置排名
                value.forEach((i)->i.setSchoolSubjectSortNum(sor.getNum()));
            });
            examStuScoRepsitory.save(examStudentScores);
        }
    }

    /**
     * 计算学生知识点得分，得分率，失分，失分率
     * @param stuIDStuScoreDetail
     * @param quesList
     * @param examSubjectStuPoint
     * @param pMap
     * examSubjectStuQuestionCalModel
     */
    public ExamSubjectStuPointCalModel calStuPoint(Map<String,StuScoreReceverModel> stuIDStuScoreDetail, List<QuestionModel> quesList, ExamSubjectStuPointCalModel examSubjectStuPoint, Map<String,List<PointCalModel>> pMap,ExamSubjectStuQuestionCalModel examSubjectStuQuestionCalModel){
        List<StudentPointCalModel> inList = new ArrayList<>();
        //按知识点分组，计算班级平均得分率
        Map<String,PointGetAvgUtil> calAvgMap = new HashMap<>();
        //按小题分组，计算班级平均得分率
        Map<String,PointGetAvgUtil> calAvgQuesMap = new HashMap<>();
        //该科目下该班级所有学生得分失分情况
        List<StudentQuestionCalModel> studentQuestionCalModelList = new ArrayList<>();
        //循环学生科目得分明细，计算知识点得分
        stuIDStuScoreDetail.forEach((stuId,scoDetail)->{
            List<StuScoreDetailModel> scoreList = scoDetail.getStuScoreDetailModels();
            StudentQuestionCalModel stuQuesCal = new StudentQuestionCalModel();
            StudentPointCalModel studentPoint = new StudentPointCalModel();
            studentPoint.setStudentId(scoDetail.getStudentId());
            studentPoint.setStudentName(scoDetail.getStudentName());
            studentPoint.setStudentNo(scoDetail.getStudentNo());
            studentPoint.setIDCard(scoDetail.getIDCard());
            BeanUtils.copyProperties(studentPoint,stuQuesCal);
            Map<String,PointCalModel> stuPoMap = new HashMap<String, PointCalModel>();
            //学生对应小题详细得分情况
            List<QuestionStuCalModel> quesDetail = new ArrayList<QuestionStuCalModel>();
            scoreList.forEach((item)->{
                QuestionStuCalModel qCal = new QuestionStuCalModel();
                qCal.setQuesNo(item.getQuestion());
                //小题实际得分
                qCal.setReceScore(Double.valueOf(item.getQuestionScore()));
                qCal.setQuesId(item.getId());
                List<QuestionModel> qli = quesList.stream().filter(q->item.getQuestion().equals(q.getQuestionNo())).collect(Collectors.toList());
                QuestionModel ques = qli.get(0);
                //小题失分
                qCal.setLoseScore(Double.valueOf(ques.getScore())- qCal.getReceScore());
                //小题得分率，失分率；
                BigDecimal re = new BigDecimal(qCal.getReceScore());
                BigDecimal tot = new BigDecimal(ques.getScore());
                qCal.setReceRate(re.divide(tot,2,BigDecimal.ROUND_HALF_UP).doubleValue());
                //失分率
                qCal.setLoseRate(1-qCal.getReceRate());
                PointGetAvgUtil pQues = calAvgQuesMap.get(qCal.getQuesNo());
                if(pQues==null){
                    pQues = new PointGetAvgUtil();
                }
                pQues.setScore(qCal.getLoseScore());
                calAvgQuesMap.put(qCal.getQuesNo(),pQues);
                quesDetail.add(qCal);
                List<PointPaperModel> poList = ques.getPointPaperListVo();
                poList.forEach((ipo)->{
                    PointCalModel po = stuPoMap.get(ipo.getPointId());
                    if(po==null){
                        po = new PointCalModel();
                        po.setPointId(ipo.getPointId());
                        po.setPointName(ipo.getPointName());
                        po.setScore(new Double(0));
                    }
                    //当前知识点得分
                    BigDecimal sco = new BigDecimal(item.getQuestionScore());
                    BigDecimal propo = new BigDecimal(ipo.getProportion()).divide(new BigDecimal(100));
                    po.setScore(po.getScore()+sco.multiply(propo).doubleValue());
                    stuPoMap.put(ipo.getPointId(),po);
                });
            });
            stuQuesCal.setQuestionStuCalModelList(quesDetail);
            studentQuestionCalModelList.add(stuQuesCal);
            List<PointStuCalModel> inpoStu = new ArrayList<PointStuCalModel>();
            stuPoMap.forEach((k,v)->{
                List<PointCalModel> listpo = pMap.get(k);
                PointCalModel p = listpo.get(0);
                PointStuCalModel postu = new PointStuCalModel();
                postu.setPointId(v.getPointId());
                postu.setPointName(v.getPointName());
                postu.setReceScore(v.getScore());   //得分
                postu.setLoseScore(p.getScore()-v.getScore());  //失分
                //计算得分率，失分率
                BigDecimal g = new BigDecimal(v.getScore());
                BigDecimal to = new BigDecimal(p.getScore());
                Double receRate = g.divide(to,2,BigDecimal.ROUND_HALF_UP).doubleValue();    //保留两位小数，四舍五入
                postu.setReceRate(receRate);
                postu.setLoseRate(1-receRate);  //失分率
                inpoStu.add(postu);
                //存放计算班级平均得分率Map
                PointGetAvgUtil avgU = calAvgMap.get(v.getPointId());
                if(avgU==null){
                    avgU = new PointGetAvgUtil();
                }
                avgU.setScore(postu.getReceRate());
                calAvgMap.put(v.getPointId(),avgU);
            });
            studentPoint.setPointStuList(inpoStu);
            inList.add(studentPoint);
        });
        examSubjectStuQuestionCalModel.setStudentQuestionCalModelList(studentQuestionCalModelList);
        examSubjectStuPoint.setStudentPoints(inList);
        List<PointCalModel> listPo = examSubjectStuPoint.getPointList();
        //设置班级知识点平均得分率，失分率
        listPo.forEach((poItem)->{
            PointGetAvgUtil avgU = calAvgMap.get(poItem.getPointId());
            poItem.setClassReceAvgRate(avgU.calAvg());
            poItem.setClassLoseAvgRate(1-poItem.getClassReceAvgRate());
        });
        //设置小题班级平均得分率
        List<QuestionCalModel> questionCalModels = examSubjectStuQuestionCalModel.getQuestionCalModels();
        for (QuestionCalModel qu:questionCalModels) {
            PointGetAvgUtil qq =  calAvgQuesMap.get(qu.getQuesNo());
            qu.setClassReceAvgScore(qq.calAvg());
            Double rate = new BigDecimal(qu.getClassReceAvgScore()).divide(new BigDecimal(qu.getScore()),4,BigDecimal.ROUND_HALF_UP).doubleValue();
            qu.setClassReceAvgRate(rate);
            qu.setClassLoseAvgRate(1-qu.getClassReceAvgRate());
        }
        //保存数据
       // pointRepsitory.save(examSubjectStuPoint);
        return examSubjectStuPoint;
    }

    /**
     * 通过考试ID，查询该考试下所有科目信息的知识点分数
     * @param
     */
    public PointUtilMode getSubjectPointByExamId(ExamModel examModel){
        PointUtilMode remo = new PointUtilMode();
        //ExamModel examModel = examRepsitory.findOne(examId);
        String examId = examModel.getId();
        //按年级科目分组
        Map<String,ExamSubjectStuPointCalModel> reMap = new HashMap<>();
        //按年级科目分组，存放所有小题信息
        Map<String,List<QuestionModel>> quesMap = new HashMap<>();
        //按年级科目分组，存放计算后的小题分析
        Map<String,ExamSubjectStuQuestionCalModel> calQuesMap = new HashMap<>();
        if(examModel==null||examModel.getExamUnitModels()==null){
            log.info("计算总平均分数据异常，查询考试信息为空。考试ID："+examId);
            return remo;
        }
        ExamSubjectStuPointCalModel examSubjectStuPoint = new ExamSubjectStuPointCalModel();
        BeanUtils.copyProperties(examModel,examSubjectStuPoint);
        //根据不同考试类型设置
        if(CalTypeEnum.examtype_school.equals(examModel.getExamType())){
            List<ExamUnitModel> unitModelList = examModel.getExamUnitModels();
            unitModelList.forEach((item)->{
                examSubjectStuPoint.setGradeId(item.getUnitId());
                examSubjectStuPoint.setGradeName(item.getUnitName());
                List<SubjectScoreModel> subjectScoreModels = item.getSubjectScoreModels();
                subjectScoreModels.forEach((subItem)->{
                    ExamSubjectStuPointCalModel examSubjectStuPointa = new ExamSubjectStuPointCalModel();
                    BeanUtils.copyProperties(examSubjectStuPoint,examSubjectStuPointa);
                    //examSubjectStuPointa.setId(GlobalUtil.createGlobalId());
                    examSubjectStuPointa.setSubjectId(subItem.getSubjectid());
                    examSubjectStuPointa.setSubjectName(subItem.getSubjectname());
                    examSubjectStuPointa.setSubjectScore(subItem.getToalscore());
                    //存放计算后小题得分情况
                    ExamSubjectStuQuestionCalModel inQues = new ExamSubjectStuQuestionCalModel();
                    BeanUtils.copyProperties(examSubjectStuPointa,inQues);
                    //inQues.setId(GlobalUtil.createGlobalId());
                    calQuesMap.put(item.getUnitId()+"-"+subItem.getSubjectid(),inQues);
                    reMap.put(item.getUnitId()+"-"+subItem.getSubjectid(),examSubjectStuPointa);
                });
            });
        }
        //班级考试
        else{
            examSubjectStuPoint.setGradeId(examModel.getGradeId());
            examSubjectStuPoint.setGradeName(examModel.getGradeName());
            List<ExamUnitModel> unitModelList = examModel.getExamUnitModels();
            //班级考试，则该参考单位只有1条数据
            List<SubjectScoreModel> subjectScoreModels = unitModelList.get(0).getSubjectScoreModels();
            subjectScoreModels.forEach((subItem)->{
                ExamSubjectStuPointCalModel examSubjectStuPointa = new ExamSubjectStuPointCalModel();
                BeanUtils.copyProperties(examSubjectStuPoint,examSubjectStuPointa);
                //examSubjectStuPointa.setId(GlobalUtil.createGlobalId());
                examSubjectStuPointa.setSubjectId(subItem.getSubjectid());
                examSubjectStuPointa.setSubjectName(subItem.getSubjectname());
                examSubjectStuPointa.setSubjectScore(subItem.getToalscore());
                //存放计算后小题得分情况
                ExamSubjectStuQuestionCalModel inQues = new ExamSubjectStuQuestionCalModel();
                BeanUtils.copyProperties(examSubjectStuPointa,inQues);
                //inQues.setId(GlobalUtil.createGlobalId());
                calQuesMap.put(examModel.getGradeId()+"-"+subItem.getSubjectid(),inQues);
                reMap.put(examModel.getGradeId()+"-"+subItem.getSubjectid(),examSubjectStuPointa);
            });
        }
        //计算每个科目各个知识点总分
        List<ExamPaperModel> paperModels = examPaperRepsitory.findByExamid(examId);
        paperModels.forEach((item)->{
            ExamSubjectStuPointCalModel re = reMap.get(item.getGradeid()+"-"+item.getSubjectid());
            //获取小题分析所需数据，存放小题信息
            ExamSubjectStuQuestionCalModel quesCal = calQuesMap.get(item.getGradeid()+"-"+item.getSubjectid());
            Map<String,List<PointCalModel>> pointMap = new HashMap<String, List<PointCalModel>>();
            if(re==null||quesCal==null){
                log.info("计算分数知识点总分异常，未找到相关年级科目信息。年级ID和科目ID为："+item.getGradeid()+"-"+item.getSubjectid());
            }
            else{
                List<QuestionModel> ques = item.getQuestionModelList();
                //该科目涉及所有小题
                List<QuestionCalModel> questionCalModels = new ArrayList<QuestionCalModel>();
                quesMap.put(item.getGradeid()+"-"+item.getSubjectid(),ques);
                //循环每个小题
                ques.forEach((qu)->{
                    //设置计算所需小题信息
                    QuestionCalModel calModel = new QuestionCalModel();
                    calModel.setQuesId(qu.getId());
                    calModel.setScore(Double.valueOf(qu.getScore()));
                    calModel.setQuesNo(qu.getQuestionNo());
                    questionCalModels.add(calModel);
                    //每个小题包含知识点
                    List<PointPaperModel> pointList = qu.getPointPaperListVo();
                    pointList.forEach((poLi)->{
                        List<PointCalModel> list = pointMap.get(poLi.getPointId());
                        if(list==null){
                            list = new ArrayList<PointCalModel>();
                        }
                        PointCalModel t = new PointCalModel();
                        t.setPointId(poLi.getPointId());
                        t.setPointName(poLi.getPointName());
                        BigDecimal sco = new BigDecimal(qu.getScore());
                        BigDecimal propo = new BigDecimal(poLi.getProportion()).divide(new BigDecimal(100));
                        t.setScore(sco.multiply(propo).doubleValue());
                        list.add(t);
                        pointMap.put(poLi.getPointId(),list);
                    });
                });
                quesCal.setQuestionCalModels(questionCalModels);
                //用于保存计算后的知识点总分集合
                List<PointCalModel> inList = new ArrayList<PointCalModel>();
                pointMap.forEach((key,value)->{
                    PointCalModel in = value.get(0);
                    //获取所有知识点总分
                    /*Optional<Double> sumScore = value.stream().map(PointCalModel::getScore).reduce(Double::sum);*/
                    Double sumScore = value.stream().mapToDouble(PointCalModel::getScore).sum();
                    in.setScore(sumScore);
                    inList.add(in);
                });
                re.setPointList(inList);
                //pointRepsitory.save(re);
            }
        });
        remo.setCalQuesMap(calQuesMap);
        remo.setQuesMap(quesMap);
        remo.setReMap(reMap);
        return remo;
    }

    /**
     * 计算班级总平均分，年级总平均分，排名等
     * @param avgMap
     * @param calTypeModel
     */
    public void calTotalAvgAndSort(Map<String,Map<String,ExamClassAvgCalModel>> avgMap, CalTypeModel calTypeModel,ExamModel examModel){
       // ExamModel examModel = examRepsitory.findOne(examId);
        String examId = examModel.getId();
        if(examModel==null||examModel.getExamUnitModels()==null){
            log.info("计算总平均分数据异常，查询考试信息为空。考试ID："+examId);
            return;
        }
        List<ExamUnitModel> listUnit = examModel.getExamUnitModels();
        //存放参考单位ID，名称信息。如果为校级考试，后面会用
        Map<String,String> listMap = listUnit.stream().collect(Collectors.toMap(ExamUnitModel::getUnitId,ExamUnitModel::getUnitName,(k1,k2)->k2));
        ExamAvgCalModel examAvgCalModel = new ExamAvgCalModel();
        examAvgCalModel.setSchoolId(examModel.getSchoolId());
        examAvgCalModel.setSchoolName(examModel.getSchoolName());
        examAvgCalModel.setExamName(examModel.getExamName());
        examAvgCalModel.setExamType(examModel.getExamType());
        examAvgCalModel.setExamId(examId);
        //按年级分组循环班级平均分信息
        avgMap.forEach((key,value)->{
            examAvgCalModel.setGradeId(key);
            examAvgCalModel.setId(GlobalUtil.createGlobalId());
            //如果为班级考试，则自己取年级信息
            if(CalTypeEnum.examtype_class.equals(examModel.getExamType())){
                examAvgCalModel.setGradeName(examModel.getGradeName());
            }
            else{
                examAvgCalModel.setGradeName(listMap.get(key));
            }
            //计算总平均分班级排名
            List<ExamClassAvgCalModel> classNumList = new ArrayList<ExamClassAvgCalModel>(value.values());
            classNumList.sort((s1,s2)->s2.getClassTotalAvgScore().compareTo(s1.getClassTotalAvgScore()));
            SortUtil s = new SortUtil();
            //schoolNumMap 按科目分组，对应班级科目平均分，排名
            Map<String,Map<String,ExamSubjectAvgCalModel>> schoolNumMap = new HashMap<String, Map<String, ExamSubjectAvgCalModel>>();
            //计算学校总平均分
            AvgUtilModel schoolAvg = new AvgUtilModel();
            classNumList.forEach(item->{
                schoolAvg.setTotalScore(schoolAvg.getTotalScore()+item.getClassTotalAvgScore());
                schoolAvg.setNum(schoolAvg.getNum()+1);
                item.setClassShortNum(s.getNum());
                //循环班级科目得分情况,用于计算班级科目平均分排名
                List<ExamSubjectAvgCalModel> subList = item.getExamSubjectAvgModel();
                subList.forEach((sub)->{
                    Map<String,ExamSubjectAvgCalModel> map = schoolNumMap.get(sub.getSubjectId());
                    if(map == null){
                        map = new HashMap<String, ExamSubjectAvgCalModel>();
                    }
                    map.put(item.getClassId(),sub);
                    schoolNumMap.put(sub.getSubjectId(),map);
                });
            });
            List<ExamSubjectSchoolAvgCalModel> totalSubAvgList = new ArrayList<ExamSubjectSchoolAvgCalModel>();
            //按科目分组，计算统计班级平均分学校排名
            schoolNumMap.forEach((key1,value1)->{
                List<ExamSubjectAvgCalModel> subNumList = new ArrayList<ExamSubjectAvgCalModel>(value1.values());
                //按科目平均分排序
                subNumList.sort((l1,l2)->l2.getClassAvgScore().compareTo(l1.getClassAvgScore()));
                s.reSetNum();
                //计算各科目总平均分
                ExamSubjectSchoolAvgCalModel subAvg = new ExamSubjectSchoolAvgCalModel();
                subAvg.setSubjectId(subNumList.get(0).getSubjectId());
                subAvg.setSubjectName(subNumList.get(0).getSubjectName());
                AvgUtilModel schoolSubAvg = new AvgUtilModel();
                subNumList.forEach((subN)->{
                    //设置排名
                    subN.setClassSubjectShortNum(s.getNum());
                    //计算各科目总平均分
                    schoolSubAvg.setTotalScore(schoolSubAvg.getTotalScore()+subN.getClassAvgScore());
                    schoolSubAvg.setNum(schoolSubAvg.getNum()+1);
                });
                subAvg.setSchoolTotalAvgScore(schoolSubAvg.calAvg(calTypeModel));
                totalSubAvgList.add(subAvg);
            });
            //计算年级总平均分，各科总平均分
            examAvgCalModel.setSchoolTotalAvgScore(schoolAvg.calAvg(calTypeModel));
            examAvgCalModel.setExamClassAvgModels(classNumList);
            //计算各科总平均分
            examAvgCalModel.setExamSubjectSchoolAvgModelList(totalSubAvgList);
            examAvgRepsitory.save(examAvgCalModel);
        });
    }

    public static void main(String[] args) {
        List<ExamSubjectAvgCalModel> subNumList = new ArrayList<>();
        List<ExamSubjectAvgCalModel> subNumList2 = new ArrayList<>();
        List<ExamSubjectAvgCalModel> subNumList3 = new ArrayList<>();
        ExamSubjectAvgCalModel a = new ExamSubjectAvgCalModel();
        a.setClassAvgScore(new Double(12));
        ExamSubjectAvgCalModel b = new ExamSubjectAvgCalModel();
        b.setClassAvgScore(new Double(18.12));
        ExamSubjectAvgCalModel c = new ExamSubjectAvgCalModel();
        c.setClassAvgScore(new Double(11.32));
        subNumList.add(a);
        subNumList2.add(b);
        subNumList3.add(c);
        subNumList.addAll(subNumList2);
        subNumList.addAll(subNumList3);
        subNumList.forEach((i)->System.out.println(i.getClassAvgScore()));
        /*Double aa = subNumList.stream().mapToDouble(ExamSubjectAvgCalModel::getClassAvgScore).sum();
        System.out.println(aa);*/
        /*Map<String,ExamSubjectAvgCalModel> map = new HashMap<>();
        map.put("11",subNumList.get(0));
        map.get("11").setClassAvgScore(new Double(100));
        subNumList.forEach((i)->System.out.println(i.getClassAvgScore()));*/
    }

    /**
     * 计算一个班级的科目平均分
     * @param scoMap
     * @param calTypeModel
     */
    public ExamClassAvgCalModel calAvg(Map<String,AvgUtilModel> scoMap, CalTypeModel calTypeModel, ExamStudentScoreCalModel examStudentScore){
        ExamClassAvgCalModel examClassAvgModel = new ExamClassAvgCalModel();
        examClassAvgModel.setClassId(examStudentScore.getClassId());
        examClassAvgModel.setClassName(examStudentScore.getClassName());
        List<ExamSubjectAvgCalModel> examSubjectAvgModelList = new ArrayList<>();
        //循环班级下各个科目总分，计算班级平均分
        scoMap.forEach((key,value)->{
            ExamSubjectAvgCalModel ExamSubjectAvgCalModel = new ExamSubjectAvgCalModel();
            ExamSubjectAvgCalModel.setSubjectId(key);
            ExamSubjectAvgCalModel.setSubjectName(value.getSubjectName());
            ExamSubjectAvgCalModel.setClassAvgScore(value.calAvg(calTypeModel));
            examSubjectAvgModelList.add(ExamSubjectAvgCalModel);
        });
        examClassAvgModel.setExamSubjectAvgModel(examSubjectAvgModelList);
        //计算班级总平均分
        Double totalAvg = examSubjectAvgModelList.stream().collect(Collectors.averagingDouble(ExamSubjectAvgCalModel :: getClassAvgScore));
        //根据模板设置小数保留规则
        examClassAvgModel.setClassTotalAvgScore(CalGetAvgUtil.getAgv(totalAvg,calTypeModel));
        return examClassAvgModel;
    }

    /**
     *计算踩线生和分数段
     */
    public ServiceResponse calScoreSelection(String examId, String gradeId){
        List<ExamStudentScoreCalModel> examStudentScores = this.examStuScoRepsitory.findByExamIdAndGradeId(examId,gradeId);
        List<ScoreSelection> scoreSelectionList = this.scoreSelectionRespository.findByExamIdAndGradeId(examId,gradeId);
        if(CollectionUtils.isEmpty(examStudentScores) || CollectionUtils.isEmpty(scoreSelectionList)){
            log.info("没有查询到考试相关信息或者没有设置分数段,exam:"+examId);
            return ServiceResponseHandle.failed("没有查询到考试相关信息或者没有设置分数段");
        }
        List<ScoreSelectionDetail> scoreSelectionDetailList = new ArrayList<>();
        scoreSelectionList.forEach(e->{
            scoreSelectionDetailList.addAll(e.getScoreSelectionDetailList());
        });

        String examType = examStudentScores.get(0).getExamType();
        List<SeleExamStudentScoreCalModel> seleExamStudentScoreCalModels = this.toSeleExamStudentScoreCalModel(examStudentScores);
        seleExamStudentScoreCalModels.forEach(seleExamStudentScoreCalModel->{
            seleExamStudentScoreCalModel.getSeleStudentScoreList().forEach(seleStudentScoreCalModel -> {
                //处理分数段
                if(scoreSelectionDetailList!=null && scoreSelectionDetailList.size()!=0){
                    scoreSelectionDetailList.forEach(scoreSelectionDetail -> {
                        this.operateSeleStudentScoreCalModel(scoreSelectionDetail,seleStudentScoreCalModel);
                    });
                }
            });
        });
        //计算班级A优、B优等在班级和年级的比率
        //取得所有的班级占比计算年级占比
        List<SeleProportion> allSeleProportionClassList = new ArrayList<>();
        seleExamStudentScoreCalModels.forEach(seleExamStudentScoreCalModel -> {
            //全班占比
            List<SeleProportion> seleProportionClassList = new ArrayList<>();
            //统计全班人数
            List<SeleStudentScoreCalModel> seleStudentScoreList = seleExamStudentScoreCalModel.getSeleStudentScoreList();
            int classCount = seleStudentScoreList.size();
            String classId = seleExamStudentScoreCalModel.getClassId();
            //统计A人数
            this.getSeleProportionClassList(seleStudentScoreList,null,seleProportionClassList,classId,classCount);
            //计算科目占比
            List<SeleSubujectScoreCalModel> seleSubujectScoreCalModels  = new ArrayList<>();
            seleStudentScoreList.forEach(e->{
                seleSubujectScoreCalModels.addAll(e.getSeleSubujectScoreList());
            });
            //分组获得所有的 科目集合
            Map<String,List<SeleSubujectScoreCalModel>> map = seleSubujectScoreCalModels.stream()
                    .filter(e-> e.getSelectValue()!=null)
                    .collect(Collectors.groupingBy(c->c.getSubjectId()));
            map.forEach((k,v)->{
                this.getSeleProportionClassList(null,v,seleProportionClassList,classId,classCount);
            });
            seleExamStudentScoreCalModel.setSeleProportionClassList(seleProportionClassList);
            //判断是否为班级考试
            if((GlobalTypeEnum.Cl.getCode()+"").equals(examType)){
                seleExamStudentScoreCalModel.setSeleProportionSchoolList(seleProportionClassList);
            }
            allSeleProportionClassList.addAll(seleProportionClassList);
        });
        //判断是否为班级考试
        if((GlobalTypeEnum.Cl.getCode()+"").equals(examType)){
            this.seleExamStudentScoreRepsitory.batchSave(seleExamStudentScoreCalModels);
            log.info("班级考试分数段分析完成:"+JSONObject.toJSONString(seleExamStudentScoreCalModels));
            return ServiceResponseHandle.success("","计算分数段完成");
        }
        //统计等级全年级总人数
        Map<String,Integer> sumMap = new HashMap<>();
        List<SeleProportion> seleProportionSchoolList = new ArrayList<>();
        //
        allSeleProportionClassList.stream().collect(Collectors.groupingBy(e->e.getSubjectId()+"-"+e.getSelectValue())).forEach((classes,seleProportionClasssList)->{
            int sum = seleProportionClasssList.stream().mapToInt(e -> e.getCount()).sum();
            if(sum !=0){
                sumMap.put(classes,sum);
            }
        });
        // 统计年级
        seleExamStudentScoreCalModels.forEach(seleExamStudentScoreCalModel -> {//
            Map<String, List<SeleProportion>> schoolMap = seleExamStudentScoreCalModel.getSeleProportionClassList().stream().collect(Collectors.groupingBy(e -> e.getSubjectId() + "-" + e.getSelectValue()));
            schoolMap.forEach((classes,seleProportionClasss)->{
                SeleProportion seleProportionSchool = new SeleProportion();
                int sum = seleProportionClasss.stream().mapToInt(SeleProportion::getCount).sum();
                String[] ids = classes.split("-");
                String subjectId =  ids[0];
                String selectValue =  ids[1];
                String temp = subjectId+"-"+selectValue;
               double proportion =  BigDecimalUtils.div(sum,sumMap.getOrDefault(temp, 1),2);
                if(!"0".equals(subjectId)){
                    seleProportionSchool.setType(GlobalTypeEnum.SUBJECT.getCode());
                }else{
                    seleProportionSchool.setType(GlobalTypeEnum.ALL.getCode());
                }
                seleProportionSchool.setSubjectId(subjectId);
                seleProportionSchool.setProportion(proportion);
                seleProportionSchool.setId(GlobalUtil.createGlobalId());
                seleProportionSchool.setSelectValue(selectValue);
                seleProportionSchool.setSelectValueName(GlobalTypeEnum.getName(Integer.parseInt(selectValue)));
                seleProportionSchoolList.add(seleProportionSchool);
            });
            seleExamStudentScoreCalModel.setSeleProportionSchoolList(seleProportionSchoolList);
        });
        JWTUserDetails userDetails = SessionUtils.getUserInfo();
        this.seleExamStudentScoreRepsitory.deleteByExamIdAndGradeIdAndClassId(examId,gradeId,userDetails.getClassId());
        this.seleExamStudentScoreRepsitory.batchSave(seleExamStudentScoreCalModels);
        log.info("成绩分数段分析完成:"+ JSONObject.toJSONString(seleExamStudentScoreCalModels));
        return ServiceResponseHandle.success("","计算分数段完成");
    }

    /**
     *  统计占比
     * @param seleStudentScoreCalModels
     * @param seleSubujectScoreCalModelList
     * @param seleProportionClassList
     * @param classId
     * @param classCount
     */
    private void getSeleProportionClassList(List<SeleStudentScoreCalModel> seleStudentScoreCalModels
            ,List<SeleSubujectScoreCalModel> seleSubujectScoreCalModelList,List<SeleProportion> seleProportionClassList,String classId,int classCount){
        GlobalTypeEnum.getListByTeamId(5).forEach(e->{
            Integer code = Integer.parseInt(e.get("code")+"");
            String name = e.get("name")+"";
            SeleProportion seleProportionClass = new SeleProportion();
            if(CollectionUtils.isEmpty(seleStudentScoreCalModels)){
                seleProportionClass.setSubjectId(seleSubujectScoreCalModelList.get(0).getSubjectId());
                seleProportionClass.setSubjectName(seleSubujectScoreCalModelList.get(0).getSubjectName());
                seleProportionClass.setType(GlobalTypeEnum.SUBJECT.getCode());
                int scoreSize = seleSubujectScoreCalModelList.stream().filter(score->code.equals(score.getSelectValue())).collect(Collectors.toList()).size();
                seleProportionClass.setProportion(BigDecimalUtils.div(new Double(scoreSize),new Double(classCount),2));
                seleProportionClass.setCount(scoreSize);
            }else{
                int scoreSize = seleStudentScoreCalModels.stream().filter(score->code.equals(score.getSelectValue())).collect(Collectors.toList()).size();
                seleProportionClass.setProportion(BigDecimalUtils.div(new Double(scoreSize),new Double(classCount),2));
                seleProportionClass.setCount(scoreSize);
                seleProportionClass.setType(GlobalTypeEnum.ALL.getCode());
                seleProportionClass.setSubjectId("0");
            }
            seleProportionClass.setId(GlobalUtil.createGlobalId());
            seleProportionClass.setSelectValue(code+"");
            seleProportionClass.setSelectValueName(name);
            seleProportionClassList.add(seleProportionClass);
        });
    }
    /**
     *  处理分数段
     * @param scoreSelectionDetail
     * @param seleStudentScoreCalModel
     * @return
     */
    private SeleStudentScoreCalModel operateSeleStudentScoreCalModel(ScoreSelectionDetail scoreSelectionDetail,SeleStudentScoreCalModel seleStudentScoreCalModel){
        double totalScore = seleStudentScoreCalModel.getTotalScore();
        double startScore = scoreSelectionDetail.getStartScore();
        double endScore =  scoreSelectionDetail.getEndScore();
        double upScore = scoreSelectionDetail.getStandardScore()+scoreSelectionDetail.getUpScore();
        double downScore = scoreSelectionDetail.getStandardScore()-scoreSelectionDetail.getDownScore();
        double standerScore = scoreSelectionDetail.getStandardScore();
        Integer selectValue = GlobalTypeEnum.getCodeByName(scoreSelectionDetail.getSelectName());
        String selectName = scoreSelectionDetail.getSelectName();
        if(GlobalTypeEnum.ALL.getCode().equals(scoreSelectionDetail.getType())){
            if(totalScore>=startScore && totalScore<=endScore){
                seleStudentScoreCalModel.setSelectValue(selectValue);
                seleStudentScoreCalModel.setSelectValueName(selectName);
            }
            if(scoreSelectionDetail.isCheck()){
                if(totalScore>=standerScore && totalScore<= upScore){
                    seleStudentScoreCalModel.setFootFaultName(scoreSelectionDetail.getFootScoreName());
                    seleStudentScoreCalModel.setFootFault(scoreSelectionDetail.getFootScoreValue());
                    seleStudentScoreCalModel.setType(GlobalTypeEnum.UP.getCode());
                    seleStudentScoreCalModel.setTypeName(GlobalTypeEnum.UP.getName());
                }
                if(totalScore<standerScore && totalScore> downScore){
                    seleStudentScoreCalModel.setFootFaultName(scoreSelectionDetail.getFootScoreName());
                    seleStudentScoreCalModel.setFootFault(scoreSelectionDetail.getFootScoreValue());
                    seleStudentScoreCalModel.setType(GlobalTypeEnum.DOWN.getCode());
                    seleStudentScoreCalModel.setTypeName(GlobalTypeEnum.DOWN.getName());
                }
            }
            return seleStudentScoreCalModel;
        }else{
            seleStudentScoreCalModel.getSeleSubujectScoreList().forEach(seleSubujectScoreCalModel -> {
                if(seleSubujectScoreCalModel.getSubjectId().equals(scoreSelectionDetail.getSubjectId())){
                    Double score = seleSubujectScoreCalModel.getScore();
                    if(score>=startScore && score<=endScore){
                        seleSubujectScoreCalModel.setSelectValue(selectValue);
                        seleSubujectScoreCalModel.setSelectValueName(selectName);
                    }
                    if(scoreSelectionDetail.isCheck()){
                        if(score>=standerScore && score<= upScore){
                            seleSubujectScoreCalModel.setFootFaultName(scoreSelectionDetail.getFootScoreName());
                            seleSubujectScoreCalModel.setFootFault(scoreSelectionDetail.getFootScoreValue());
                            seleSubujectScoreCalModel.setType(GlobalTypeEnum.UP.getCode());
                            seleSubujectScoreCalModel.setTypeName(GlobalTypeEnum.UP.getName());
                        }
                        if(score<standerScore && score> downScore){
                            seleSubujectScoreCalModel.setFootFaultName(scoreSelectionDetail.getFootScoreName());
                            seleSubujectScoreCalModel.setFootFault(scoreSelectionDetail.getFootScoreValue());
                            seleSubujectScoreCalModel.setType(GlobalTypeEnum.DOWN.getCode());
                            seleSubujectScoreCalModel.setTypeName(GlobalTypeEnum.DOWN.getName());
                        }
                    }
                }
            });
        }



        return seleStudentScoreCalModel;
    }
    /**
     *  转换对应的对象
     * @param examStudentScoreCalModelList
     * @return
     */
    private List<SeleExamStudentScoreCalModel> toSeleExamStudentScoreCalModel(List<ExamStudentScoreCalModel> examStudentScoreCalModelList){
        List<SeleExamStudentScoreCalModel> seleExamStudentScoreCalModels = new ArrayList<>();
        examStudentScoreCalModelList.forEach(e->{
            SeleExamStudentScoreCalModel seleExamStudentScoreCalModel = new SeleExamStudentScoreCalModel();
            BeanUtils.copyProperties(e,seleExamStudentScoreCalModel);
            List<SeleStudentScoreCalModel> seleStudentScoreCalModels = new ArrayList<>();
            e.getStudentScoreList().forEach(studentScoreCalModel -> {
                List<SeleSubujectScoreCalModel> seleSubujectScoreCalModels = new ArrayList<>();
                SeleStudentScoreCalModel seleStudentScoreCalModel = new SeleStudentScoreCalModel();
                seleStudentScoreCalModel.setId(GlobalUtil.createGlobalId());
                BeanUtils.copyProperties(studentScoreCalModel,seleStudentScoreCalModel);
                studentScoreCalModel.getSubujectScoreList().forEach(subujectScoreCalModel -> {
                    SeleSubujectScoreCalModel seleSubujectScoreCalModel = new SeleSubujectScoreCalModel();
                    seleSubujectScoreCalModel.setId(GlobalUtil.createGlobalId());
                    BeanUtils.copyProperties(subujectScoreCalModel,seleSubujectScoreCalModel);
                    seleSubujectScoreCalModels.add(seleSubujectScoreCalModel);
                });
                seleStudentScoreCalModel.setSeleSubujectScoreList(seleSubujectScoreCalModels);
                seleStudentScoreCalModels.add(seleStudentScoreCalModel);
            });
            seleExamStudentScoreCalModel.setSeleStudentScoreList(seleStudentScoreCalModels);
            seleExamStudentScoreCalModels.add(seleExamStudentScoreCalModel);
        });
        return seleExamStudentScoreCalModels;
    }
}
